#include "precompiled.h"
#pragma hdrstop


namespace inf {
    /*
    ============
    Rotation::to_Angles
    ============
    */
    Angles Rotation::to_Angles( void ) const {
        return to_Mat3().to_Angles();
    }

    /*
    ============
    Rotation::to_Quat
    ============
    */
    Quat Rotation::to_Quat( void ) const {
        float a, s, c;

        a = angle * ( math::M_DEG2RAD * 0.5f );
        math::sincos( a, s, c );
        return Quat( vec.x * s, vec.y * s, vec.z * s, c );
    }

    /*
    ============
    Rotation::toMat3
    ============
    */
    const Mat3 &Rotation::to_Mat3( void ) const {
        float wx, wy, wz;
        float xx, yy, yz;
        float xy, xz, zz;
        float x2, y2, z2;
        float a, c, s, x, y, z;

        if ( axisValid ) {
            return axis;
        }

        a = angle * ( math::M_DEG2RAD * 0.5f );
        math::sincos( a, s, c );

        x = vec[0] * s;
        y = vec[1] * s;
        z = vec[2] * s;

        x2 = x + x;
        y2 = y + y;
        z2 = z + z;

        xx = x * x2;
        xy = x * y2;
        xz = x * z2;

        yy = y * y2;
        yz = y * z2;
        zz = z * z2;

        wx = c * x2;
        wy = c * y2;
        wz = c * z2;

        axis[ 0 ][ 0 ] = 1.0f - ( yy + zz );
        axis[ 0 ][ 1 ] = xy - wz;
        axis[ 0 ][ 2 ] = xz + wy;

        axis[ 1 ][ 0 ] = xy + wz;
        axis[ 1 ][ 1 ] = 1.0f - ( xx + zz );
        axis[ 1 ][ 2 ] = yz - wx;

        axis[ 2 ][ 0 ] = xz - wy;
        axis[ 2 ][ 1 ] = yz + wx;
        axis[ 2 ][ 2 ] = 1.0f - ( xx + yy );

        axisValid = true;

        return axis;
    }

    /*
    ============
    Rotation::to_Mat4
    ============
    */
    Mat4 Rotation::to_Mat4( void ) const {
        return to_Mat3().to_Mat4();
    }

    /*
    ============
    Rotation::to_angular_velocity
    ============
    */
    Vec3 Rotation::to_angular_velocity( void ) const {
        return vec * math::DEG2RAD( angle );
    }

    /*
    ============
    Rotation::normalize_180
    ============
    */
    void Rotation::normalize_180( void ) {
        angle -= math::floor( angle / 360.0f ) * 360.0f;
        if ( angle > 180.0f ) {
            angle -= 360.0f;
        }
        else if ( angle < -180.0f ) {
            angle += 360.0f;
        }
    }

    /*
    ============
    Rotation::normalize_360
    ============
    */
    void Rotation::normalize_360( void ) {
        angle -= math::floor( angle / 360.0f ) * 360.0f;
        if ( angle > 360.0f ) {
            angle -= 360.0f;
        }
        else if ( angle < 0.0f ) {
            angle += 360.0f;
        }
    }

}   // ::inf
